#include "Task.hpp"
#include "BlockQueue.hpp"
#include <unistd.h>

// 消费者、生产者和交易场景，交易场景就是stl数据结构中一种,消费者、生产者是线程
// 执行线程函数把数据插入队列，消费者执行线程函数从队列拿数据就是在交易
// 问题转换为如何编写阻塞队列

struct ThreadData
{
    BlockQueue<Task> *bq;
    std::string name;
};
void *consumer(void *args)
{
    ThreadData *td = static_cast<ThreadData *>(args);
    while (true)
    {
        sleep(1);
        Task t;
        // 1. 从交易场所中，获取数据或者任务
        td->bq->Pop(&t);
        // 2.消费数据
        t();
        t.Print();
    }
}
void *productor(void *args)
{
    ThreadData *td = static_cast<ThreadData *>(args);
    int data=1;
    while (true)
    {
        // 1. 生产者，你的数据从哪里来？网路或者其他主机
        int x = data;
        int y = data + 1;
        Task t(x, y);
        data++;
        td->bq->Enqueue(t);
        std::cout << "生产者生产了一个任务" << std::endl;
    }
}
int main()
{
    // 既可以传递数据，也可以派发任务！！！
    BlockQueue<Task> *bq = new BlockQueue<Task>();
    pthread_t c, p;

    ThreadData ctd = {bq, "消费者"};
    pthread_create(&c, nullptr, consumer, (void *)&ctd);

    ThreadData ptd = {bq, "生产者"};
    pthread_create(&p, nullptr, productor, (void *)&ptd);

    pthread_join(c, nullptr);
    pthread_join(p, nullptr);

    
    //多生产多消费
    // pthread_t c[2], p[3];

    // ThreadData ctd = {bq, "消费者"};
    // pthread_create(c+0, nullptr, consumer, (void*)&ctd); 
    // pthread_create(c+1, nullptr, consumer, (void*)&ctd); 

    // ThreadData ptd = {bq, "生产者"};
    // pthread_create(p+0, nullptr, productor, (void*)&ptd); // TODO
    // pthread_create(p+1, nullptr, productor, (void*)&ptd); // TODO
    // pthread_create(p+2, nullptr, productor, (void*)&ptd); // TODO


    // pthread_join(c[0], nullptr);
    // pthread_join(c[1], nullptr);
    // pthread_join(p[0], nullptr);
    // pthread_join(p[1], nullptr);
    // pthread_join(p[2], nullptr);

    delete bq;
    return 0;
}